<template>
  <div>
    <el-card class="case_edit_box">
      <div class="env_select">
        <span style="font-weight:bold;padding-right:10px">测试环境</span>
        <el-select v-model="env" placeholder="请选择环境">
          <el-option v-for="e in envs" :key="'env'+e.id" :label="e.name" :value="e.id"></el-option>
        </el-select>
      </div>
      <el-divider content-position="left">
        <b>Api</b>
      </el-divider>
      <div>
        <el-row :gutter="10">
          <el-col :span="4">
            <el-select v-model="method" placeholder="请选择">
              <el-option label="GET" value="get"></el-option>
              <el-option label="POST" value="post"></el-option>
              <el-option label="PUT" value="pyt"></el-option>
              <el-option label="DELETE" value="delete"></el-option>
              <el-option label="PATCH" value="patch"></el-option>
              <el-option label="OPTION" value="option"></el-option>
            </el-select>
          </el-col>
          <el-col :span="20">
            <el-input label="host" v-model="host">
              <template slot="prepend">Host</template>
            </el-input>
          </el-col>
        </el-row>

        <el-row :gutter="10" style="margin-top:10px">
          <el-col :span="20">
            <el-input v-model="url">
              <template slot="prepend">接口地址</template>
              <el-select v-model="interface" slot="append" placeholder="请选择接口" style="width:150px">
                <el-option
                  v-for="inter in interfaces"
                  :key="'inter'+inter.id"
                  :label="inter.name"
                  :value="inter.id"
                ></el-option>
              </el-select>
            </el-input>
          </el-col>
          <el-col :span="4">
            <el-button type="primary" icon="el-icon-s-promotion" @click="RunCase">Run</el-button>
          </el-col>
        </el-row>

        <el-divider content-position="left">
          <b>Request</b>
        </el-divider>

        <el-tabs>
          <el-tab-pane label="请求头">
            <KeyValueInputVue :datas="headers"></KeyValueInputVue>
          </el-tab-pane>
          <el-tab-pane label="请求参数">
            <el-tabs>
              <el-tab-pane label="Params">
                <KeyValueInputVue :datas="params"></KeyValueInputVue>
              </el-tab-pane>
              <el-tab-pane label="x-www-form-urlencoded">
                <KeyValueInputVue :datas="data"></KeyValueInputVue>
              </el-tab-pane>
              <el-tab-pane label="json">
                <Editor
                  style="height:200px"
                  language="json"
                  theme="chrome"
                  :readOnly="false"
                  v-model="jsonParams"
                ></Editor>
                <el-button type="primary" @click="jsonFormat" size="mini">json数据格式化</el-button>
              </el-tab-pane>
            </el-tabs>
          </el-tab-pane>
          <el-tab-pane label="响应提取">
            <KeyValueInputVue :datas="extract"></KeyValueInputVue>
          </el-tab-pane>
          <el-tab-pane label="用例断言">
            <AssertInput :datas="assertion" :way="way" name="实际结果提取表达式"></AssertInput>
          </el-tab-pane>
          <el-tab-pane label="数据库校验">
            <AssertInput :datas="db_assertion" :way="way" name="sql语句"></AssertInput>
          </el-tab-pane>
        </el-tabs>

        <el-divider content-position="left">
          <b>Case Desc</b>
        </el-divider>

        <div>
          <el-row :gutter="10" style="margin-bottom:5px">
            <el-col :span="12">
              <el-input v-model="title" placeholder="用例名称">
                <template slot="prepend">用例名称</template>
              </el-input>
            </el-col>
            <el-col :span="12">
              <el-input v-model="marks" placeholder="用例标签">
                <template slot="prepend">用例标签</template>
              </el-input>
            </el-col>
          </el-row>

          <el-row :gutter="10" style="margin-bottom:5px">
            <el-col :span="12">
              <el-input v-model="tester" placeholder="编写人员">
                <template slot="prepend">编写人员</template>
              </el-input>
            </el-col>
            <el-col :span="12">
              <el-input v-model="res_type" placeholder="响应类型">
                <template slot="prepend">响应类型</template>
              </el-input>
            </el-col>
          </el-row>

          <el-row :gutter="10" style="margin-bottom:5px">
            <el-col :span="12">
              <el-input v-model="status_code" placeholder="用例名称">
                <template slot="prepend">运行状态码</template>
              </el-input>
            </el-col>
            <el-col :span="12">
              <el-input v-model="order" placeholder="序号">
                <template slot="prepend">序号</template>
              </el-input>
            </el-col>
          </el-row>
        </div>

        <el-button type="primary" @click="SaveCase">保存用例</el-button>
        <CaseResponse :response_obj="response_obj" />
      </div>
    </el-card>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import Editor from '@/components/Edit.vue'
import KeyValueInputVue from './KeyValueInput.vue'
import AssertInput from '@/components/casePage/AssertInput'
import CaseResponse from './CaseResponse.vue'

export default {
  // import引入的组件需要注入到对象中才能使用
  components: { Editor, KeyValueInputVue, AssertInput, CaseResponse },
  props: {},
  data() {
    return {
      env: null,
      host: '',
      url: '',
      method: 'get',
      title: '',
      tester: '',
      marks: '',
      status_code: null,
      res_type: '',
      order: null,
      interface: '',
      headers: [['', '']],
      data: [['', '']],
      params: [['', '']],
      extract: [['', '']],
      assertion: [['', '', '']],
      db_assertion: [['', '', '']],
      jsonParams: '{}',
      way: ['eq'],
      caseData: {},
      response_obj: {},
    }
  },
  computed: {
    ...mapState(['envs', 'pro', 'interfaces', 'caseId']),
  },
  watch: {
    env: function (val, oldVal) {
      if (val) {
        const env = this.envs.find((item, index) => {
          return item.id === val
        })
        this.host = env.host
      }
    },
    interface: function (val, oldVal) {
      if (val) {
        const iter_ = this.interfaces.find((item, index) => {
          return item.id === val
        })
        this.url = iter_.url
      }
    },
    caseId: function (val, oldVal) {
      if (val.indexOf('_') === -1 && val) {
        this.getTestCase(val)
      }
    },
  },
  methods: {
    jsonFormat() {
      const jsonObj = JSON.parse(this.jsonParams)
      this.jsonParams = JSON.stringify(jsonObj, null, 4)
    },
    async getTestCase(id) {
      console.log(id)
      const response = await this.$api.getCase(id)
      if (response.status === 200) {
        this.caseData = response.data
        this.initCaseData()
      }
    },
    initCaseData() {
      this.interface = this.caseData.interface
      this.method = this.caseData.method
      this.title = this.caseData.title
      this.tester = this.caseData.tester
      this.marks = this.caseData.marks
      this.status_code = this.caseData.status_code
      this.res_type = this.caseData.res_type
      this.order = this.caseData.order
      this.assertion = JSON.parse(this.caseData.assertion)
      this.extract = JSON.parse(this.caseData.extract)
      this.db_assertion = JSON.parse(this.caseData.db_assertion)
      const request_obj = JSON.parse(this.caseData.request)
      this.jsonParams = JSON.stringify(request_obj.json, null, 4)
      this.headers = this.objToArray(request_obj.headers)
      this.data = this.objToArray(request_obj.data)
      this.params = this.objToArray(request_obj.params)
    },
    objToArray(obj) {
      let arr = []
      for (let key in obj) {
        arr.push([key, obj[key]])
      }
      return arr
    },
    arrayToObj(arr) {
      let obj = {}
      if (arr !== undefined) {
        for (let item of arr) {
          obj[item[0]] = item[1]
        }
      }
      return obj
    },
    resetCaseData() {
      this.caseData.assertion = JSON.stringify(this.assertion)
      this.caseData.extract = JSON.stringify(this.extract)
      this.caseData.db_assertion = JSON.stringify(this.db_assertion)
      console.log(this.headers)
      console.log(this.arrayToObj(this.headers))
      this.caseData.request = JSON.stringify({
        headers: this.arrayToObj(this.headers),
        data: this.arrayToObj(this.data),
        params: this.arrayToObj(this.params),
        json: JSON.parse(this.jsonParams),
      })
    },
    // 保存用例数据
    async SaveCase() {
      this.resetCaseData()
      const response = await this.$api.updateCase(
        this.caseData.id,
        this.caseData
      )
      if (response.status === 200) {
        this.$message({
          message: '保存成功!',
          type: 'success',
        })
      }
    },
    async RunCase() {
      this.resetCaseData()
      const url = this.host + this.url
      const method = this.method
      console.log(this.caseData.request)
      const request = JSON.parse(this.caseData.request)
      const response = await this.$api.runCase({ url, method, request })
      if (response.status === 200) {
        this.response_obj = response.data
        this.$message({
          message: '请求成功',
          type: 'success',
        })
      }
    },
  },
  created() {},
}
</script>
<style scoped>
.case_edit_box {
  height: calc(100vh - 100px);
  overflow-y: auto;
  overflow-x: hidden;
}
.env_select {
  line-height: 60px;
}
</style>